-- Scheme for Stalkers with gulag jobs to turn on their smart's campfires --[[ scheme_type: generic author: Alundaio modified_by: --]] -------------------- evaid = 188114 actid = 188114 -------------------- ------------------------------------------------------------- -- PRIVATE ------------------------------------------------------------- already_selected = {} local function eval_reset(st) if (st.selected_id) then already_selected[st.selected_id] = nil st.selected_id = nil end st.vid = nil st.__stimer = nil st.camp = nil st.state = nil if (st.npc and state_mgr.get_state(st.npc) == "light_campfire") then state_mgr.set_state(st.npc,"guard") end return false end ------------------------------------------------------------- -- ON GAME START ------------------------------------------------------------- function on_game_start() end ------------------------------------------------------------- -- PUBLIC ------------------------------------------------------------- function light_campfire(npc) local id = npc:id() local st = db.storage[id] and db.storage[id].turn_on_campfire local camp = st and st.selected_id and level.object_by_id(st.selected_id) if not (camp) then return eval_reset(st) end local CFZone = camp:get_campfire() if not (CFZone) then return eval_reset(st) end if (render_get_dx_level() == 655361) then camp:enable_anomaly() end if (CFZone:is_on()) then return eval_reset(st) end CFZone:turn_on() eval_reset(st) end ------------------------------------------------------------- -- eva_turn_on_campfire ------------------------------------------------------------- class "eva_turn_on_campfire" (property_evaluator) function eva_turn_on_campfire:__init(npc,name,storage) super (nil,name) self.st = storage end function eva_turn_on_campfire:find_valid_target() local npc = self.object if (self.st.selected_id) then if (already_selected[self.st.selected_id] == npc:id()) then local camp = level.object_by_id(self.st.selected_id) local CFZone = camp and camp:get_campfire() if (CFZone and not CFZone:is_on()) then return true end end --already_selected[self.st.selected_id] = nil self.st.selected_id = nil end local tg = time_global() self.st.__dtimer = not self.st.__dtimer and tg + 5000 or self.st.__dtimer if (tg < self.st.__dtimer) then return false end local smart = xr_gulag.get_npc_smart(npc) if not (smart) then return false end -- NPC not entered smart local npc_info = smart.npc_info[npc:id()] if not (npc_info and npc_info.job) then return false end if (npc_info.job.exclusive and xr_logic.pick_section_from_condlist(db.actor, npc, self.st.allow) == "false") then return false end local campfires = db.campfire_table_by_smart_names[smart:name()] if (campfires == nil or is_empty(campfires)) then return false end local is_dx11 = render_get_dx_level() == 655361 local npc_id = npc:id() local selected_id for id,binder in pairs(campfires) do if (binder.object and binder.campfire) then if (already_selected[id] == nil and not binder.campfire:is_on()) then if (self.st.selected_id and already_selected[self.st.selected_id]) then already_selected[self.st.selected_id] = nil end self.st.selected_id = id already_selected[id] = npc:id() self.st.vid = binder.object:level_vertex_id() self.st.pos = binder.object:position() self.st.state = binder.object:position():distance_to_sqr(npc:position()) > 900 and "rush" or "patrol" return true end end end return false end function eva_turn_on_campfire:evaluate() --utils_data.debug_write("eva_turn_on_campfire") local npc = self.object if (npc:alive() ~= true or IsWounded(npc)) then return false end if (xr_danger.has_danger(npc)) then return false end if (npc:best_enemy() or xr_conditions.surge_started()) then return false end local st = db.storage[npc:id()] if (st and st.active_scheme == "camper") then return false end --[[ local hrs = level.get_time_hours() if not (hrs < 6 or hrs > 19) then return false end --]] -- testing --if (state_mgr.get_state(npc) == "roast_kolbasa") then --return true --end if (self:find_valid_target()) then return true end return false end ------------------------------------------------------ -- act_turn_on_campfire ------------------------------------------------------ class "act_turn_on_campfire" ( action_base ) function act_turn_on_campfire:__init(npc,name,storage) super (nil,name) self.st = storage end function act_turn_on_campfire:initialize() local npc = self.object npc:set_desired_position() npc:set_desired_direction() npc:set_path_type(game_object.level_path) self.st.vid = utils_obj.send_to_nearest_accessible_vertex(npc,self.st.vid,"turn_on_campfire") state_mgr.set_state(npc,self.st.state or "patrol") action_base.initialize(self) end function act_turn_on_campfire:execute() action_base.execute(self) local npc = self.object if (state_mgr.get_state(npc) == "light_campfire") then local tg = time_global() self.st.__stimer = not self.st.__stimer and tg + 10000 or self.st.__stimer if (tg > self.st.__stimer) then light_campfire(npc) end return end local pos = self.st.pos local dist = pos:distance_to_sqr(npc:position()) if (npc:level_vertex_id() == self.st.vid or dist <= 1.5) then state_mgr.set_state(npc, "light_campfire",nil,nil,{look_position = pos}) --[[ testing state_mgr.set_state(npc, "roast_kolbasa",nil,nil,{look_position = pos}) local kamp = self.st.camp:get_campfire() if (kamp and not kamp:is_on()) then kamp:turn_on() end --]] else if (npc:path_type() ~= game_object.level_path) then npc:set_path_type(game_object.level_path) end state_mgr.set_state(npc,self.st.state or "patrol") self.st.vid = utils_obj.send_to_nearest_accessible_vertex(npc, self.st.vid,"turn_on_campfire") end end function act_turn_on_campfire:finalize() action_base.finalize(self) eval_reset(self.st) end ---------------------------------------------------------------------------------------------------------------------- -- BINDER ---------------------------------------------------------------------------------------------------------------------- function setup_generic_scheme(npc,ini,scheme,section,stype,temp) local st = xr_logic.assign_storage_and_bind(npc,ini,"turn_on_campfire",section,temp) end function add_to_binder(npc,char_ini,scheme,section,st,temp) if not npc then return end local manager = npc:motivation_action_manager() if not manager then return end if (not npc:alive()) or (character_community(npc) == "zombied" or npc:section() == "actor_visual_stalker") then manager:add_evaluator(evaid,property_evaluator_const(false)) temp.needs_configured = false return end local wp = world_property local evaluator = eva_turn_on_campfire(npc,"eval_turn_on_campfire", st) temp.action = act_turn_on_campfire(npc,"action_turn_on_campfire", st) if not evaluator or not temp.action then return end manager:add_evaluator(evaid, evaluator) temp.action:add_precondition(wp(evaid, true)) temp.action:add_precondition(wp(stalker_ids.property_alive,true)) temp.action:add_precondition(wp(stalker_ids.property_enemy,false)) temp.action:add_precondition(wp(stalker_ids.property_danger,false)) temp.action:add_effect(wp(evaid, false)) manager:add_action(actid,temp.action) end function configure_actions(npc,ini,scheme,section,stype,temp) if not npc then return end local manager = npc:motivation_action_manager() if not manager or not temp.action then return end local wp = world_property --temp.action:add_precondition(wp(xr_evaluators_id.state_mgr + 2,true)) if (_G.schemes["gather_items"]) then temp.action:add_precondition(wp(xr_gather_items.evaid, false)) end temp.action:add_precondition(wp(xr_evaluators_id.wounded_exist,false)) if (_G.schemes["corpse_detection"]) then temp.action:add_precondition(wp(xr_evaluators_id.corpse_exist,false)) end temp.action:add_precondition(wp(xr_evaluators_id.stohe_meet_base + 1, false)) temp.action:add_precondition(wp(xr_evaluators_id.sidor_wounded_base, false)) temp.action:add_precondition(wp(xr_evaluators_id.abuse_base, false)) --temp.action:add_precondition( wp(xr_evaluators_id.state_mgr + 1,false) ) local action local p = { xr_actions_id.state_mgr + 2, xr_actions_id.alife } for i=1,#p do --printf("ACTION_ALIFE_ID(axr_turn_on_campfire.configure_actions): " .. tostring(p[i])) action = manager:action(p[i]) if (action) then action:add_precondition( wp(evaid,false) ) else printf("xr_corpse_detection: no action id p[%s]",i) end end end function reset_generic_scheme(npc,scheme,section,stype,st) if (st.turn_on_campfire) then st.turn_on_campfire.allow = xr_logic.parse_condlist(npc, section, "turn_on_campfire", st.ini:r_string_ex(section,"turn_on_campfire") or "false") eval_reset(st.turn_on_campfire) end end function npc_add_precondition(action) if not action then return end action:add_precondition(world_property(evaid,false)) end function is_under_turn_on_campfire(npc) local mgr = npc:motivation_action_manager() if not mgr or not mgr:initialized() then return false end return mgr:current_action_id() == actid end